package net.kylewu.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

import net.kylewu.RCFFCommands;
import net.kylewu.RCFFProperties;
import net.kylewu.ThreadRunner;

import org.dom4j.DocumentException;
import org.dyno.visual.swing.layouts.Bilateral;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;

/**
 * Main Frame
 * 
 * @author Kyle Wu
 * 
 */
// VS4E -- DO NOT REMOVE THIS LINE!
public class MainFrame extends JFrame {

	private static final long serialVersionUID = 1L;

	// Swing Components
	private JScrollPane jScrollPane0;
	private JToolBar jToolBar;

	private JButton jBtnStart;
	private JButton jBtnStop;
	private JButton jBtnSetting;
	private JButton jBtnAbout;
	private JButton jBtnQuit;

	private JTextArea jTextArea;

	// Timer & Thread
	private Timer timer;
	private ThreadRunner tc;

	// Properties & commands
	private RCFFProperties rcffProperties;
	private RCFFCommands rcffCommands;

	private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";

	public MainFrame() {
		initComponents();
		init();
	}

	private void init() {

		// Get Properties from files
		try {
			// if exception throws, then do not init others
			rcffProperties = new RCFFProperties();
			rcffCommands = new RCFFCommands();

			// Timer
			timer = new Timer(1000 * rcffProperties.getIntervalTime(),
					new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							// jTextArea.append("It's our time.\n");
							tc = new ThreadRunner(rcffProperties, rcffCommands,
									jTextArea);
							tc.start();
						}
					});

			if (rcffProperties.isAutoStart()) {
				jBtnStart.setEnabled(false);
				timer.start();
			} else {
				jBtnStop.setEnabled(false);
			}

		} catch (DocumentException e) {
			jTextArea.append("Error occurs while reading property file.\n");
			jTextArea.append("Please check your property file and restart.\n");
			jBtnStart.setEnabled(false);
			jBtnStop.setEnabled(false);
			jBtnSetting.setEnabled(false);
		} catch (UnsupportedEncodingException e) {
			jTextArea.append("Error occurs while reading command file.\n");
			jTextArea.append("Please check your command file and restart.\n");
			jBtnStart.setEnabled(false);
			jBtnStop.setEnabled(false);
			jBtnSetting.setEnabled(false);
		}

	}

	private void initComponents() {
		setTitle("RemoteControl -- Kyle Wu");
		setFont(new Font("Dialog", Font.PLAIN, 12));
		setExtendedState(Frame.MAXIMIZED_BOTH);
		setForeground(Color.black);
		setLayout(new GroupLayout());
		add(getJToolBar(), new Constraints(new Bilateral(0, 0, 136),
				new Leading(0, 22, 10, 10)));
		add(getJScrollPane(), new Constraints(new Bilateral(11, 11, 22),
				new Bilateral(29, 12, 22)));
		setSize(320, 240);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	private JButton getJBtnQuit() {
		if (jBtnQuit == null) {
			jBtnQuit = new JButton();
			jBtnQuit.setText("Quit");
			jBtnQuit.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent event) {
					jBtnQuitActionActionPerformed(event);
				}
			});
		}
		return jBtnQuit;
	}

	private JButton getJBtnAbout() {
		if (jBtnAbout == null) {
			jBtnAbout = new JButton();
			jBtnAbout.setText("About");
			jBtnAbout.setRolloverEnabled(false);
			jBtnAbout.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent event) {
					jBtnAboutActionActionPerformed(event);
				}
			});
		}
		return jBtnAbout;
	}

	private JButton getJBtnSetting() {
		if (jBtnSetting == null) {
			jBtnSetting = new JButton();
			jBtnSetting.setText("Setting");
			jBtnSetting.setRolloverEnabled(false);
			jBtnSetting.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent event) {
					jBtnSettingActionActionPerformed(event);
				}
			});
		}
		return jBtnSetting;
	}

	private JButton getJBtnStop() {
		if (jBtnStop == null) {
			jBtnStop = new JButton();
			jBtnStop.setText("Stop");
			jBtnStop.setRolloverEnabled(false);
			jBtnStop.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent event) {
					jBtnStopActionActionPerformed(event);
				}
			});
		}
		return jBtnStop;
	}

	private JButton getJBtnStart() {
		if (jBtnStart == null) {
			jBtnStart = new JButton();
			jBtnStart.setText("Start");
			jBtnStart.setRolloverEnabled(false);
			jBtnStart.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent event) {
					jBtnStartActionActionPerformed(event);
				}
			});
		}
		return jBtnStart;
	}

	private JScrollPane getJScrollPane() {
		if (jScrollPane0 == null) {
			jScrollPane0 = new JScrollPane();
			jScrollPane0.setViewportView(getJTextArea());
		}
		return jScrollPane0;
	}

	private JTextArea getJTextArea() {
		if (jTextArea == null) {
			jTextArea = new JTextArea();
			jTextArea.setEnabled(false);
			jTextArea.setFocusCycleRoot(true);
		}
		return jTextArea;
	}

	private JToolBar getJToolBar() {
		if (jToolBar == null) {
			jToolBar = new JToolBar();
			jToolBar.add(getJBtnStart());
			jToolBar.add(getJBtnStop());
			jToolBar.add(getJBtnSetting());
			jToolBar.add(getJBtnAbout());
			jToolBar.add(getJBtnQuit());
		}
		return jToolBar;
	}

	private static void installLnF() {
		try {
			String lnfClassname = PREFERRED_LOOK_AND_FEEL;
			if (lnfClassname == null)
				lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
			UIManager.setLookAndFeel(lnfClassname);
		} catch (Exception e) {
			System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
					+ " on this platform:" + e.getMessage());
		}
	}

	private void jBtnStartActionActionPerformed(ActionEvent event) {
		// jTextArea.append("Start Button Pressed\n");
		timer.start();
		jBtnStart.setEnabled(false);
		jBtnStop.setEnabled(true);

	}

	private void jBtnStopActionActionPerformed(ActionEvent event) {
		// jTextArea.append("Stop Button Pressed\n");
		timer.stop();
		tc.interrupt();
		jBtnStop.setEnabled(false);
		jBtnStart.setEnabled(true);

	}

	private void jBtnSettingActionActionPerformed(ActionEvent event) {
		// jTextArea.append("Setting Button Pressed\n");
		OptionsDialog od;
		try {
			od = new OptionsDialog(rcffProperties, rcffCommands);
			od.setLocationRelativeTo(this);
			// od.pack();
			od.setModal(true);
			od.setVisible(true);
		} catch (UnsupportedEncodingException e) {
			jTextArea.append("Error while reading file\n");
		} catch (DocumentException e) {
			jTextArea.append("Error while reading file\n");
		}

	}

	private void jBtnAboutActionActionPerformed(ActionEvent event) {
		// jTextArea.append("About Button Pressed\n");
		AboutDialog ad = new AboutDialog();
		ad.setLocationRelativeTo(this);
		ad.setModal(true);
		ad.pack();
		ad.setVisible(true);

	}

	private void jBtnQuitActionActionPerformed(ActionEvent event) {
		// jTextArea.append("Quit Button Pressed\n");
		if (timer != null)
			timer.stop();
		if (tc != null)
			tc.interrupt();
		this.dispose();
	}

	/**
	 * Main entry of the class. Note: This class is only created so that you can
	 * easily preview the result at runtime. It is not expected to be managed by
	 * the designer. You can modify it as you like.
	 */
	public static void main(String[] args) {
		installLnF();
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				MainFrame frame = new MainFrame();
				frame.setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
				// frame.setTitle("MainFrame");
				frame.getContentPane().setPreferredSize(frame.getSize());
				frame.pack();
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}

}
